/**
 *
 */
package cn.edu.cqu.bysj.wm.ago.lp;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.neo4j.graphdb.GraphDatabaseService;
import org.neo4j.graphdb.Node;
import org.neo4j.tooling.GlobalGraphOperations;

import cn.edu.cqu.bysj.wm.ago.anlys.Similarity;
import cn.edu.cqu.bysj.wm.def.ConstDef;
import cn.edu.cqu.bysj.wm.def.PropertyDef;
import cn.edu.cqu.bysj.wm.util.NodeComparator;

/**
 * @author Meng
 * 
 */
public class LPCommunity {

	// map of community id and nodes
	public static Map<Long, List<Node>> communitys;

	// map of community label and nodes
	public static Map<Integer, List<Node>> labelCommunitys;

	// map of community id and label
	public static Map<Long, Integer> communityLabel;

	// map of community size and community number
	public static Map<Integer, Integer> cscn;

	private static long CID;

	/**
	 * show all community detected in LP
	 * 
	 * @param gdb
	 */
	public static void showCommunity(GraphDatabaseService gdb) {

		labelCommunitys = new HashMap<Integer, List<Node>>();
		communityLabel = new HashMap<Long, Integer>();
		communitys = new HashMap<Long, List<Node>>();

		CID = 0;
		recordCommunity(gdb);

		// solution number added
		Similarity.SID++;

		// fill communitys
		for (Entry<Integer, List<Node>> e : labelCommunitys.entrySet()) {

			if (e.getValue().size() >= ConstDef.MIN_COMMUNITY_SIZE) {
				communityLabel.put(++CID, e.getKey());
				Collections.sort(e.getValue(), new NodeComparator());
				communitys.put(CID, e.getValue());
			}
		}
		// solution info added
		Similarity.solutions.put(Similarity.SID, communitys);
	}

	/**
	 * fill map of labelCommunity
	 * 
	 * @param gdb
	 */
	private static void recordCommunity(GraphDatabaseService gdb) {

		for (Node node : GlobalGraphOperations.at(gdb).getAllNodes()) {
			// jump over the reference node
			if (node.getId() != 0) {
				int lab = (Integer) node.getProperty(PropertyDef.LABEL);
				if (labelCommunitys.containsKey(lab)) {
					labelCommunitys.get(lab).add(node);
				} else {
					List<Node> list = new ArrayList<Node>();
					list.add(node);
					labelCommunitys.put(lab, list);
				}
			}
		}
	}

	/**
	 * fill map of cscn 
	 */
	public static void sizeNumber() {

		cscn = new HashMap<Integer, Integer>();

		for (long i : communitys.keySet()) {
			int size = communitys.get(i).size();
			if (cscn.containsKey(size)) {
				cscn.put(size, cscn.get(size) + 1);
			} else {
				cscn.put(size, 1);
			}
		}
	}

}
